#pragma once

#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <boost/filesystem.hpp>
#include <openvino/openvino.hpp>

#include "aes.h"
#include "modes.h"
#include "filters.h"
// #include "../txr_algo_dlm_v5/common/define.h"
#include <fstream>
#include <vector>
#include <iostream>
#include <filesystem> // C++17标准库中的文件系统库




// 定义新结构体，用于存储长度信息
struct st_encrypt_header {
	size_t struct_size;   // st_encrypt_info_ovino结构体的大小
	size_t xml_size;      // XML文件的大小
	size_t bin_size;      // BIN文件的大小
};

// 最大锚点数量和步幅数量定义
static constexpr int MAX_NUM_ANCHORS = 4;
static constexpr int MAX_STRIDES = 4;

// st_encrypt_info_ovino 结构体用于存储加密模型的相关信息
struct st_encrypt_info_ovino {
	char gpu_model[100] = {0}; // 存储 GPU 型号，字符数组初始化为 0

	int batch_size = 0; // 批处理大小
	int class_num = 0; // 分类数量
	int input_channel = 0; // 输入通道数
	int image_width = 0; // 输入图像的宽度
	int image_height = 0; // 输入图像的高度

	int num_anchors_size = 0; // 实际锚点数量
	int num_anchors[MAX_NUM_ANCHORS] = {0}; // 存储每种锚点的数量

	int stride_num = 0; // 步幅的数量
	int strides[MAX_STRIDES] = {0}; // 存储不同步幅

	bool dynamic = false; // 选择是否动态分配
	int engine_size = 0; // 引擎大小


	float obj_threshold{};            // 目标检测阈值
	float nms_threshold{};            // 非极大值抑制阈值

};


//==========================================================================================
enum PRECISION_MODE // 精度模式枚举
{
	PRECISION_FP32, // 浮点数 32 位（单精度浮点数）
	PRECISION_FP16, // 浮点数 16 位（半精度浮点数）
	PRECISION_INT8, // 8 位整型
};

// st_trans_model_input 结构体包含模型输入信息
struct st_trans_model_input
{
	std::string cfg_path; // 配置文件路径
	std::string model_path; // 模型文件路径

	PRECISION_MODE precision = PRECISION_FP16; // 设置默认精度为 FP16
	std::string gpu_model = "Intel(R) UHD Graphics 630"; // 使用的 GPU 型号

	std::string trans_path; // 转换后的文件路径
};

namespace fs = boost::filesystem;

class yolo_v6 {
public:
	yolo_v6();
	~yolo_v6();

	/**
	 * @brief 转换 YOLO v6 模型文件为 OpenVINO IR 并加密
	 * @param input 转换输入结构，包含配置文件路径和其他信息
	 * @return 转换成功返回 true，否则返回 false
	 */
	static bool TransModel(const st_trans_model_input& input);
};